Bingo, Computer Graphics & Game Developer
这一篇主要记录PBRT中Path Tracing的理解笔记。一旦涉及到了代码层面的实现,会显得无从下手。
首先是路径追踪的蒙特卡洛估计量写法
路径追踪加上了直接光采样,本质上就是应用重要性采样以及对于Dirac delta Distribution等的处理。
如图所示
使用一简化后的路径追踪表达式(省略了pdf,russian rullte,以及立体角到面积形式的表示,改变了累乘的上限)
意味着,当前追踪到的点上求得的直接光照,是用来计算上一节点的Reflected Radiance的。令表示光源,那么直接光采样得到的结果,表示当前点位置处,向反射的光照,因此需要在计算直接光照时,乘以权重(仅表意,严格来讲这里是做了一次多重重要性采样)
因此这里点处计算得到的直接光照,被用于点用作间接光照/反射光来传递给下一节点。由于运用了光路可逆,因此在代码实现过程中循环过程会是相反的,也就是正向追踪光路。
这一事实较难以直接从公式中get到,下方通过PBRT源代码验证。
PBRT通过保存一个pathThroughput变量,用于记录原式子右边的累乘项
for (int bounces = 0; ; ++bounces)
{
// 逆向计算直接光照在上一节点的贡献/反射光照
Vector wo = -ray.d;
L += pathThroughput * UniformSampleOneLight(wo,...);
// 计算当前结点BRDF以及出射方向
Spectrum f = bsdf->Sample_f(wo, wi, pdf...);
// 式子中的累乘项,晚于直接光照的计算
pathThroughput *= f * AbsDot(wi, n) / pdf;
// 新的跟踪光线
ray = Ray(p, wi, ...);
if (bounces == maxDepth) break;
if (!scene->Intersect(ray,...))
{
// 无限远区域光光照
L += pathThroughput * infiniteLight;
break;
}
}
return L;
因此在理解增量形式路径追踪的实际实现时,最关键的点为以下两点
1.当前追踪到的点上计算得到的直接光照,是作用于上一节点的反射光照上的。
2.循环中累乘项应晚于直接光照计算,因此其累乘项截止到上一节点为止。